/*
 * Created: Author: Aléx Carvalho / Date: Mar 16, 2015
 * 
 * Changed: $Author: ac280593@gmail.com $ / $Date: 2015-06-12 00:38:01 -0300 (Fri, 12 Jun 2015) $
 */
package com.cpm.view.zk.applications;

import com.cpm.ServiceLocator;
import com.cpm.aggregate.SessionAttribute;
import com.cpm.business.SemaphoreColor;
import com.cpm.context.SessionContext;
import com.cpm.view.IconKit;
import com.cpm.entities.Indicator;
import com.cpm.entities.Node;
import com.cpm.entities.StrategicPlan;
import com.cpm.view.Alerts;
import com.cpm.view.CSSClass;
import com.cpm.view.zk.MenuAction;
import com.cpm.view.zk.field.SearchField;
import com.cpm.view.zk.editors.indicator.IndicatorEditor;
import com.cpm.view.zk.tree.DefaultTreeNode;
import com.cpm.view.zk.tree.structure.StructureTree;
import com.cpm.view.zk.treetable.indicator.IndicatorTreeTable;
import com.cpm.view.Icon;
import com.cpm.view.zk.IconElement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Optional;
import org.zkoss.zk.ui.HtmlBasedComponent;
import org.zkoss.zk.ui.HtmlNativeComponent;
import org.zkoss.zul.Div;
import org.zkoss.zul.West;

public class StructureApplication extends AbstractApplication {

    private final West west = new West();
    private final IndicatorTreeTable indicatorTreeTable = new IndicatorTreeTable();
    private final StructureTree structureTree = new StructureTree();
    private final SearchField searchField = new SearchField();
    private HtmlBasedComponent center;
    private boolean modeEdit = false;

    private void editNode() {
        Node node = structureTree.getSelectedValue();

        if (node == null) {
            Alerts.getInstance().showInfo("Selecione um item");
            return;
        }

        if (node.isIndicator()) {
            modeEdit = true;

            IndicatorEditor editor = new IndicatorEditor((Indicator) node, source -> updateNode(source));

            editor.setCallbackClose(value -> {
                updateCenter();
                modeEdit = false;
            });

            showEditor(editor);
        }
        else if (node.isFolder()) {

        }
    }

    private void addNode() {
    }

    private void deleteNode() {
        structureTree.getSelectedNode().removeFromParent();
    }

    private void updateNode(Node node) {
        ServiceLocator.getNodeRepository().update(node);
        DefaultTreeNode<Node> treeNode = structureTree.getSelectedNode();
        treeNode.setData(node);
        structureTree.renderItems();
    }

    public StructureApplication() {
        initComponents();
    }

    @Override
    protected void getMenuActions(LinkedHashSet<MenuAction> menuActions) {

        MenuAction add = new MenuAction(new Icon(IconKit.ADD), "Adicionar", (e) -> addNode());
        MenuAction edit = new MenuAction(new Icon(IconKit.EDIT), "Editar", (e) -> editNode());
        MenuAction delete = new MenuAction(new Icon(IconKit.DELETE), "Delete", (e) -> deleteNode());

        menuActions.add(edit);
        menuActions.add(add);
        menuActions.add(delete);
    }

    @Override
    protected HtmlBasedComponent getComponentCenter() {
        return center;
    }

    @Override
    public Optional<West> getWest() {
        return Optional.of(west);
    }

    @Override
    public String getLabel() {
        return "Estrutura";
    }

    @Override
    public Icon getIcon() {
        return new Icon(IconKit.EDIT);
    }

    @Override
    public Double getPosition() {
        return 2.0;
    }

    @Override
    protected void initializeData() {
        indicatorTreeTable.buildTree();
        structureTree.buildTree();
    }

    private void updateTreeSelection() {
        if (modeEdit) {
            editNode();
        }
        else {

            Collection<Indicator> indicators = new ArrayList<>(0);

            structureTree.getSelectedNode().getChildren().forEach(node -> {
                DefaultTreeNode no = (DefaultTreeNode) node;

                if (no.getData() instanceof Indicator) {
                    indicators.add((Indicator) no.getData());
                }
            });

            indicatorTreeTable.setIndicators(indicators);
            indicatorTreeTable.buildTree();
        }
    }

    private void initComponents() {

        StrategicPlan plan = ServiceLocator.lookup(SessionContext.class).getAttribute(SessionAttribute.STRATEGIC_PLAN);
        
        structureTree.setStrategicPlan(plan);
        
        west.setWidth("250px");
        west.setSplittable(true);
        west.setBorder("none");

        Div divWest = new Div();
        divWest.setHflex("true");
        divWest.setVflex("true");

        Div menu = new Div();
        menu.setSclass(CSSClass.MENU_BAR.toString());
        menu.appendChild(searchField.getElement());

        Div planNode = new Div();
        planNode.setSclass("z-treecell-content");

        HtmlNativeComponent planLabel = new HtmlNativeComponent("span");
        planLabel.setDynamicProperty("class", "z-treecell-text");
        planLabel.setEpilogContent(plan.getName());

        CSSClass color = ServiceLocator.lookup(SemaphoreColor.class).getSemaphoreColorToStrategicPlan(plan);
        
        IconElement planIcon = new IconElement( new Icon(IconKit.STRATEGIC_PLAN, color, CSSClass.STRUCTURE_PLAN ) );
        
        planLabel.appendChild(planIcon.getElement());

        planNode.appendChild(planLabel);

        divWest.appendChild(menu);
        divWest.appendChild(planNode);
        divWest.appendChild(structureTree.getElement());

        west.appendChild(divWest);

        structureTree.addSelectionListener(e -> updateTreeSelection());

        center = indicatorTreeTable.getElement();
    }
}
